package priv.pfz.basedao.mybatis.sqlprovider;

import org.apache.ibatis.builder.annotation.ProviderContext;
import priv.pfz.basedao.Utils;
import priv.pfz.basedao.info.FieldInfo;
import priv.pfz.basedao.info.DaoInfo;
import priv.pfz.basedao.mybatis.DaoInfoCache;
import priv.pfz.basedao.sharding.ShardingInfo;
import priv.pfz.basedao.sharding.ShardingManager;
import priv.pfz.basedao.sqlbuilder.SQL;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * INSERT INTO table (a,b,c) VALUES (entity1.a, entity1.b, entity1.c), (entity2.a, entity2.b, entity2.c), ...
 * @author yyjxp
 * 2024/1/28 23:55
 * todo 暂不支持 INSERT INTO table () VALUES (),();
 */
public class BatchInsertSqlProvider extends BaseSqlProvider {

    public String provideSql(Iterable<?> entities, ProviderContext context) {
        return innerProvideSql(entities, null, context);
    }

    public String provideShardingSql(Iterable<?> entities, ShardingInfo shardingInfo, ProviderContext context) {
        return innerProvideSql(entities, shardingInfo, context);
    }

    private String innerProvideSql(Iterable<?> entities, ShardingInfo shardingInfo, ProviderContext context) {
        Utils.checkNotEmpty(entities, "entities不能为空");
        DaoInfo daoInfo = DaoInfoCache.getDaoInfo(context.getMapperType());
        ShardingManager shardingManager = new ShardingManager(daoInfo, shardingInfo);

        SQL sql = new SQL();
        Iterator<?> iterator = entities.iterator();
        Set<String> insertFields = null;
        for (int i = 0; iterator.hasNext(); i++) {
            Object entity = iterator.next();
            Map<String, Object> valueMap = getValueMap(daoInfo, entity);
            if (i == 0) {
                Utils.checkNotEmpty(valueMap, "entities[0]字段不能全部为空");
                insertFields = valueMap.keySet();
                for (FieldInfo fieldInfo : daoInfo.getFieldInfos()) {
                    if (!valueMap.containsKey(fieldInfo.getFieldName())) {
                        continue;
                    }
                    sql.INTO_COLUMNS(fieldInfo.getColumnSql());
                }
                if (daoInfo.isEnableLogicDelete()) {
                    sql.INTO_COLUMNS(daoInfo.getLogicDeleteColumnSql());
                }
            }
            for (FieldInfo fieldInfo : daoInfo.getFieldInfos()) {
                if (!insertFields.contains(fieldInfo.getFieldName())) {
                    continue;
                }
                sql.INTO_VALUES(getFieldNamePlaceHolder("arg0", i, fieldInfo));
                Object value = valueMap.get(fieldInfo.getFieldName());
                Utils.checkNotNull(value, "insert的字段不能为空");
                shardingManager.addShardingInfo(fieldInfo, value);
            }
            if (daoInfo.isEnableLogicDelete()) {
                sql.INTO_VALUES("0");
            }
            sql.ADD_ROW();
        }
        sql.INSERT_INTO(shardingManager.getShardingTable());
        String sqlStr = sql.toString();
        sqlStr += shardingManager.getThirdShardingStr();
        System.out.println(sqlStr);
        return sqlStr;
    }
}